

#define GPIO_WriteLow(GPIOx,a)    GPIOx->BSRR=(((uint32_t)(uint8_t)~(a))<<16)|((uint32_t)(uint8_t)(a))
#define GPIO_WriteHigh(GPIOx,a)    GPIOx->BSRR=(((uint8_t)(uint8_t)~(a))<<24)|(((uint32_t)(uint8_t)(a))<<8)

// 读取当前 CRH 寄存器的值
uint32_t crh = GPIOB->CRH;

// 配置输入模式
// 上拉输入: CNF1:CNF0 = 10, MODE1:MODE0 = 00
const uint32_t PULLUP_INPUT = 0b1000;
// 浮空输入: CNF1:CNF0 = 01, MODE1:MODE0 = 00
const uint32_t FLOATING_INPUT = 0b0100;

// 配置输出模式
// 推挽输出: CNF1:CNF0 = 00, MODE1:MODE0 = 11 (50MHz)
const uint32_t PUSHPULL_OUTPUT = 0b0011;
// 开漏输出: CNF1:CNF0 = 01, MODE1:MODE0 = 11 (50MHz)
const uint32_t OPENDRAIN_OUTPUT = 0b0111;

// 设置单个引脚的输出电平
void GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t PIN, uint8_t state) {
    if(state) {
        GPIOx->BSRR = PIN;  // 设置为高电平
    } else {
        GPIOx->BRR = PIN;   // 设置为低电平
    }
}

void read_mode(void){
  // pinMode(Data0, INPUT_PULLUP);
  // pinMode(Data1, INPUT_PULLUP);
  // pinMode(Data2, INPUT_PULLUP);
  // pinMode(Data3, INPUT_PULLUP);
  // pinMode(Data4, INPUT_PULLUP);
  // pinMode(Data5, INPUT_PULLUP);
  // pinMode(Data6, INPUT_PULLUP);
  // pinMode(Data7, INPUT_PULLUP);

  crh = GPIOB->CRH;
  // 清除 PB8-PB15 的配置位
  crh &= 0x00000000;
  
  // 配置 PB8
  crh |= (PULLUP_INPUT << (4 * 0));  // PB8
  crh |= (PULLUP_INPUT << (4 * 1));  // PB9
  crh |= (PULLUP_INPUT << (4 * 2));  // PB10
  crh |= (PULLUP_INPUT << (4 * 3));  // PB11
  crh |= (PULLUP_INPUT << (4 * 4));  // PB12
  crh |= (PULLUP_INPUT << (4 * 5));  // PB13
  crh |= (PULLUP_INPUT << (4 * 6));  // PB14
  crh |= (PULLUP_INPUT << (4 * 7));  // PB15
  
  // 写入新的配置到 CRH 寄存器
  GPIOB->CRH = crh;
}

void write_mode(void){
  // pinMode(Data0, OUTPUT);
  // pinMode(Data1, OUTPUT);
  // pinMode(Data2, OUTPUT);
  // pinMode(Data3, OUTPUT);
  // pinMode(Data4, OUTPUT);
  // pinMode(Data5, OUTPUT);
  // pinMode(Data6, OUTPUT);
  // pinMode(Data7, OUTPUT);

  // 读取当前 CRH 寄存器的值
  crh = GPIOB->CRH;
  
  // 清除 PB8-PB15 的配置位
  crh &= 0x00000000;
  
  // 配置 PB8-PB15
  crh |= (PUSHPULL_OUTPUT << (4 * 0));  // PB8
  crh |= (PUSHPULL_OUTPUT << (4 * 1));  // PB9
  crh |= (PUSHPULL_OUTPUT << (4 * 2));  // PB10
  crh |= (PUSHPULL_OUTPUT << (4 * 3));  // PB11
  crh |= (PUSHPULL_OUTPUT << (4 * 4));  // PB12
  crh |= (PUSHPULL_OUTPUT << (4 * 5));  // PB13
  crh |= (PUSHPULL_OUTPUT << (4 * 6));  // PB14
  crh |= (PUSHPULL_OUTPUT << (4 * 7));  // PB15
  
  // 写入新的配置到 CRH 寄存器
  GPIOB->CRH = crh;

}

// 只设置一次
void addressOutput(void){
  pinMode(A_0, OUTPUT);
  pinMode(A_1, OUTPUT);
  pinMode(A_2, OUTPUT);
  pinMode(A_3, OUTPUT);
  pinMode(A_4, OUTPUT);
  pinMode(A_5, OUTPUT);
  pinMode(A_6, OUTPUT);
  pinMode(A_7, OUTPUT);
  pinMode(A_8, OUTPUT);
  pinMode(A_9, OUTPUT);
  pinMode(A_10, OUTPUT);
  pinMode(A_11, OUTPUT);
  pinMode(A_12, OUTPUT);
  pinMode(A_13, OUTPUT);
  pinMode(A_14, OUTPUT);
  pinMode(A_15, OUTPUT);
  pinMode(A_16, OUTPUT);
  pinMode(A_17, OUTPUT);
  pinMode(A_18, OUTPUT);
}



// 读取数据
uint8_t read_data_bus(void) {
//  return ((digitalRead(Data7) << 7) +
//          (digitalRead(Data6) << 6) +
//          (digitalRead(Data5) << 5) +
//          (digitalRead(Data4) << 4) +
//          (digitalRead(Data3) << 3) +
//          (digitalRead(Data2) << 2) +
//          (digitalRead(Data1) << 1) +
//          digitalRead(Data0));
  return ((GPIOB->IDR) >>8) & 0xff;
}

void write_data_bus(uint16_t dataa){
//  digitalWrite(Data0, data & 1);//也可使用移位 data & (1 << 0)
//  digitalWrite(Data1, (data >> 1) & 1);
//  digitalWrite(Data2, (data >> 2) & 1);
//  digitalWrite(Data3, (data >> 3) & 1);
//  digitalWrite(Data4, (data >> 4) & 1);
//  digitalWrite(Data5, (data >> 5) & 1);
//  digitalWrite(Data6, (data >> 6) & 1);
//  digitalWrite(Data7, (data >> 7) & 1);
  //GPIOB->ODR = dataa<<8;
  GPIO_WriteHigh(GPIOB, dataa & 0xff);
}
void setAddress(uint32_t addr) {
//  digitalWrite(A_0, (addr >> 0) & 1);
//  digitalWrite(A_1, (addr >> 1) & 1);
//  digitalWrite(A_2, (addr >> 2) & 1);
//  digitalWrite(A_3, (addr >> 3) & 1);
//  digitalWrite(A_4, (addr >> 4) & 1);
//  digitalWrite(A_5, (addr >> 5) & 1);
//  digitalWrite(A_6, (addr >> 6) & 1);
//  digitalWrite(A_7, (addr >> 7) & 1);

  PBout(0)=(addr >> 0) & 1;
  PBout(1)=(addr >> 1) & 1;
  PAout(10)=(addr >> 2) & 1;
  PBout(3)=(addr >> 3) & 1;
  PBout(4)=(addr >> 4) & 1;
  PBout(5)=(addr >> 5) & 1;
  PBout(6)=(addr >> 6) & 1;
  PBout(7)=(addr >> 7) & 1;
  
//  GPIOB->ODR = addr & 0xff;
//  digitalWrite(A_2, (addr >> 2) & 1);
  
//  GPIO_WriteLow(GPIOB, addr & 0xff);
//  digitalWrite(A_2, (addr >> 2) & 1);
  
//  digitalWrite(A_8, (addr >> 8) & 1);
//  digitalWrite(A_9, (addr >> 9) & 1);
//  digitalWrite(A_10, (addr >> 10) & 1);
//  digitalWrite(A_11, (addr >> 11) & 1);
//  digitalWrite(A_12, (addr >> 12) & 1);
//  digitalWrite(A_13, (addr >> 13) & 1);
//  digitalWrite(A_14, (addr >> 14) & 1);
//  digitalWrite(A_15, (addr >> 15) & 1);
//  GPIOA->ODR = addr>>8 & 0xff;

  GPIO_WriteLow(GPIOA,(addr>>8)&0xff);

  // digitalWrite(A_16, (addr >> 16) & 1);
  // digitalWrite(A_17, (addr >> 17) & 1);
  // digitalWrite(A_18, (addr >> 18) & 1);

  // GPIO_WritePin(GPIOC, GPIO_PIN_14, (addr >> 16) & 1);
  // GPIO_WritePin(GPIOC, GPIO_PIN_15, (addr >> 17) & 1);
  // GPIO_WritePin(GPIOA, GPIO_PIN_15, (addr >> 18) & 1);

  
  PCout(14)=(addr >> 16) & 1;
  PCout(15)=(addr >> 17) & 1;
  PAout(15)=(addr >> 18) & 1;


}



